const db = uniCloud.database()
const cmd = db.command
const $ = db.command.aggregate
const uniIdCommon = require('uni-id-common')

// 抽离的独立函数
async function checkUserAuth(ctx) {
	// 检查ctx参数
	if (!ctx) {
		console.error('checkUserAuth: ctx 参数为空')
		return {
			errCode: 'UNAUTHORIZED',
			errMsg: '未登录或登录已过期'
		}
	}

	// 检查用户信息
	if (!ctx.authInfo || !ctx.authInfo.uid) {
		console.error('checkUserAuth: 用户未登录', ctx)
		return {
			errCode: 'UNAUTHORIZED',
			errMsg: '请先登录'
		}
	}

	return null
}

module.exports = {
	async _before() {
		try {
			const token = this.getUniIdToken()
			if (!token) return

			const clientInfo = this.getClientInfo()
			const uniIdInstance = uniIdCommon.createInstance({
				clientInfo
			})

			const payload = await uniIdInstance.checkToken(token)
			if (payload.errCode) return

			const userInfo = await db.collection('uni-id-users')
				.doc(payload.uid)
				.get()

			if (userInfo.data && userInfo.data.length > 0) {
				this.ctx = {
					authInfo: {
						uid: payload.uid,
						...userInfo.data[0]
					}
				}
			}
		} catch (error) {
			console.error('Token验证失败:', error)
		}
	},

	async _after(error, result) {
		if (error) {
			return {
				errCode: 'SYSTEM_ERROR',
				errMsg: '服务器错误'
			}
		}
		return result
	},

	// 获取帖子列表
	async getPosts(params) {
		const { type, page = 1, pageSize = 10, searchKey = '', userId } = params
		const db = uniCloud.database()
		const $ = db.command.aggregate
		const dbCmd = db.command

		let matchCondition = {}
		
		// 如果有搜索关键词
		if (searchKey) {
			matchCondition = {
				$or: [
					{ content: { $regex: searchKey, $options: 'i' } },  // 使用$regex进行内容搜索
					{ tags: searchKey }  // 标签精确匹配
				]
			}
		}

		// 根据不同类型设置不同的查询条件
		switch (type) {
			case 'hot':
				// 热门帖子，结合时间、点赞数和评论数计算热度
				matchCondition.createTime = dbCmd.gte(Date.now() - 7 * 24 * 60 * 60 * 1000) // 最近7天
				// 移除matchCondition中的排序条件，改用aggregate的sort
				break
			case 'follow':
				// 关注的用户的帖子
				const followRes = await db.collection('follows')
					.where({
						followerId: userId
					})
					.get()
				const followingIds = followRes.data.map(item => item.followeeId)
				matchCondition.userId = dbCmd.in(followingIds)
				// 排除自己的帖子
				matchCondition.userId = dbCmd.and([
					dbCmd.in(followingIds),
					dbCmd.neq(userId)
				])
				break
			case 'nearby':
				// 附近的帖子，需要用户位置信息
				// TODO: 实现基于地理位置的查询
				break
			default:
				// 最新帖子，按时间排序
				break
		}

		try {
			console.log('匹配条件：',matchCondition)
			const res = await db.collection('posts')
				.aggregate()
				.match(matchCondition)
				.lookup({
					from: 'uni-id-users',
					localField: 'userId',
					foreignField: '_id',
					as: 'userInfo'
				})
				.unwind('$userInfo')
				.addFields({
					// 计算热度分数
					hotScore: {
						$cond: {
							if: { $eq: [type, 'hot'] },
							then: {
								$add: [
									// 点赞权重：1点赞 = 1分
									{ $ifNull: ['$likeCount', 0] },
									// 评论权重：1评论 = 2分
									{ $multiply: [{ $ifNull: ['$commentCount', 0] }, 2] },
									// 收藏权重：1收藏 = 3分
									{ $multiply: [{ $ifNull: ['$collectionCount', 0] }, 3] },
									// 时间衰减因子：越新分数越高
									{
										$divide: [
											1000000,
											{
												$add: [
													1,
													{
														$subtract: [
															Date.now(),
															{ $ifNull: ['$createTime', Date.now()] }
														]
													}
												]
											}
										]
									}
								]
							},
							else: 0
						}
					}
				})
				.sort(
					type === 'hot' ?
					{
						hotScore: -1, // 热门帖子按热度分数排序
						createTime: -1 // 热度相同时，按时间排序
					} : {
						createTime: -1 // 其他情况按时间排序
					}
				)
				.skip((page - 1) * pageSize)
				.limit(pageSize)
				.end()

			// 处理返回数据，添加是否点赞、收藏等状态
			const posts = res.data.map(post => {
				return {
					...post,
					isLiked: post.likes && post.likes.includes(userId),
					isCollected: post.collections && post.collections.includes(userId),
					// 确保tags字段存在
					tags: post.tags || [],
					// 移除不需要的字段
					hotScore: undefined,
					likes: undefined,
					collections: undefined
				}
			})

			// 新增：批量查询关注关系，添加isFollowing字段
			let followingIds = []
			if (userId && posts.length > 0) {
				const authorIds = posts.map(post => post.userId)
				const followRes = await db.collection('follows')
					.where({
						followerId: userId,
						followeeId: dbCmd.in(authorIds)
					})
					.get()
				followingIds = followRes.data.map(item => item.followeeId)
			}
			const postsWithFollow = posts.map(post => ({
				...post,
				isFollowing: followingIds.includes(post.userId) || post.userId === userId
			}))

			return {
				code: 0,
				data: postsWithFollow
			}
		} catch (error) {
			console.error('获取帖子列表失败：', error)
			return {
				code: 500,
				msg: '获取帖子列表失败'
			}
		}
	},

	// 创建帖子
	async createPost(params) {
		const authCheckResult = await checkUserAuth(this.ctx)
		if (authCheckResult) return authCheckResult

		const {
			content,
			images = [],
			tags = []
		} = params

		if (!content?.trim()) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '内容不能为空'
			}
		}

		const processedTags = tags.map(tag => tag.trim()).filter(tag => tag)

		const post = {
			userId: this.ctx.authInfo.uid,
			content: content.trim(),
			images,
			tags: processedTags,
			status: 1,
			likes: [],
			likeCount: 0,
			collections: [],
			collectionCount: 0,
			createTime: Date.now(),
			updateTime: Date.now()
		}

		const res = await db.collection('posts').add(post)

		return {
			errCode: 0,
			data: res.id,
			errMsg: '发布成功',
			shouldClose: true
		}
	},

	// 添加评论
	async addComment(params) {
		const {
			postId,
			content,
			replyTo = null  // 回复某条评论的ID，默认为null
		} = params

		// 参数验证
		if (!postId) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '帖子ID不能为空'
			}
		}

		if (!content?.trim()) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '评论内容不能为空'
			}
		}

		// 检查帖子是否存在
		const postResult = await db.collection('posts')
			.doc(postId)
			.get()

		if (!postResult.data || postResult.data.length === 0) {
			return {
				errCode: 'POST_NOT_FOUND',
				errMsg: '帖子不存在'
			}
		}

		// 如果是回复其他评论，检查被回复的评论是否存在
		if (replyTo) {
			const replyComment = await db.collection('article_comments')
				.doc(replyTo)
				.get()

			if (!replyComment.data || replyComment.data.length === 0) {
				return {
					errCode: 'COMMENT_NOT_FOUND',
					errMsg: '被回复的评论不存在'
				}
			}
		}

		// 创建评论
		const comment = {
			postId,
			userId: this.ctx.authInfo.uid,
			content: content.trim(),
			replyTo,
			createTime: Date.now(),
			updateTime: Date.now(),
			status: 1  // 1: 正常, 0: 删除
		}

		const res = await db.collection('article_comments').add(comment)

		// 更新帖子的评论计数
		await db.collection('posts')
			.doc(postId)
			.update({
				commentCount: cmd.inc(1)
			})

		return {
			errCode: 0,
			data: res.id,
			errMsg: '评论成功'
		}
	},

	// 点赞/取消点赞
	async toggleLike(params) {
		const { postId } = params

		// 参数验证
		if (!postId) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '帖子ID不能为空'
			}
		}

		// 检查帖子是否存在
		const postResult = await db.collection('posts')
			.doc(postId)
			.get()

		if (!postResult.data || postResult.data.length === 0) {
			return {
				errCode: 'POST_NOT_FOUND',
				errMsg: '帖子不存在'
			}
		}

		const post = postResult.data[0]
		const likes = post.likes || []
		const userId = this.ctx.authInfo.uid
		const isLiked = likes.includes(userId)

		try {
			if (isLiked) {
				// 已点赞，取消点赞
				const result = await db.collection('posts')
					.doc(postId)
					.update({
						likes: cmd.pull(userId),
						likeCount: cmd.inc(-1)
					})

				// 获取更新后的点赞计数
				const updatedPost = await db.collection('posts')
					.doc(postId)
					.get()

				return {
					errCode: 0,
					errMsg: '取消点赞成功',
					isLiked: false,
					likeCount: updatedPost.data[0].likeCount
				}
			} else {
				// 未点赞，添加点赞
				const result = await db.collection('posts')
					.doc(postId)
					.update({
						likes: cmd.push(userId),
						likeCount: cmd.inc(1)
					})

				// 获取更新后的点赞计数
				const updatedPost = await db.collection('posts')
					.doc(postId)
					.get()

				return {
					errCode: 0,
					errMsg: '点赞成功',
					isLiked: true,
					likeCount: updatedPost.data[0].likeCount
				}
			}
		} catch (error) {
			throw error
		}
	},

	// 获取点赞状态
	async getLikeStatus(params) {
		const { postId } = params

		// 参数验证
		if (!postId) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '帖子ID不能为空'
			}
		}

		// 查询点赞状态
		const post = await db.collection('posts')
			.doc(postId)
			.get()

		if (!post.data || post.data.length === 0) {
			return {
				errCode: 'POST_NOT_FOUND',
				errMsg: '帖子不存在'
			}
		}

		const likes = post.data[0].likes || []
		return {
			errCode: 0,
			isLiked: likes.includes(this.ctx.authInfo.uid)
		}
	},

	// 收藏/取消收藏
	async toggleCollection(params) {
		const { postId } = params

		// 参数验证
		if (!postId) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '帖子ID不能为空'
			}
		}

		// 检查帖子是否存在
		const postResult = await db.collection('posts')
			.doc(postId)
			.get()

		if (!postResult.data || postResult.data.length === 0) {
			return {
				errCode: 'POST_NOT_FOUND',
				errMsg: '帖子不存在'
			}
		}

		const post = postResult.data[0]
		const collections = post.collections || []
		const userId = this.ctx.authInfo.uid
		const isCollected = collections.includes(userId)

		try {
			if (isCollected) {
				// 已收藏，取消收藏
				const result = await db.collection('posts')
					.doc(postId)
					.update({
						collections: cmd.pull(userId),
						collectionCount: cmd.inc(-1)
					})

				// 获取更新后的收藏计数
				const updatedPost = await db.collection('posts')
					.doc(postId)
					.get()

				return {
					errCode: 0,
					errMsg: '取消收藏成功',
					isCollected: false,
					collectionCount: updatedPost.data[0].collectionCount
				}
			} else {
				// 未收藏，添加收藏
				const result = await db.collection('posts')
					.doc(postId)
					.update({
						collections: cmd.push(userId),
						collectionCount: cmd.inc(1)
					})

				// 获取更新后的收藏计数
				const updatedPost = await db.collection('posts')
					.doc(postId)
					.get()

				return {
					errCode: 0,
					errMsg: '收藏成功',
					isCollected: true,
					collectionCount: updatedPost.data[0].collectionCount
				}
			}
		} catch (error) {
			throw error
		}
	},

	// 获取收藏状态
	async getCollectionStatus(params) {
		const { postId } = params

		// 参数验证
		if (!postId) {
			return {
				errCode: 'PARAM_ERROR',
				errMsg: '帖子ID不能为空'
			}
		}

		// 查询收藏状态
		const post = await db.collection('posts')
			.doc(postId)
			.get()

		if (!post.data || post.data.length === 0) {
			return {
				errCode: 'POST_NOT_FOUND',
				errMsg: '帖子不存在'
			}
		}

		const collections = post.data[0].collections || []
		return {
			errCode: 0,
			isCollected: collections.includes(this.ctx.authInfo.uid)
		}
	},

	// 获取用户收藏的帖子列表
	async getCollectedPosts(params) {
		const {
			page = 1,
			pageSize = 10
		} = params

		const skip = (page - 1) * pageSize

		const aggregate = db.collection('posts')
			.aggregate()
			.match({
				collections: this.ctx.authInfo.uid
			})
			.lookup({
				from: 'uni-id-users',
				let: { userId: '$userId' },
				pipeline: [
					{ $match: { $expr: { $eq: ['$_id', '$$userId'] } } },
					{ $project: { nickname: 1, avatar: 1 } }
				],
				as: 'userInfo'
			})
			.unwind('$userInfo')
			.addFields({
				isLiked: {
					$in: [this.ctx.authInfo.uid, { $ifNull: ['$likes', []] }]
				},
				isCollected: true,
				likeCount: {
					$size: { $ifNull: ['$likes', []] }
				},
				collectionCount: {
					$size: { $ifNull: ['$collections', []] }
				}
			})
			.project({
				likes: 0,
				collections: 0
			})
			.sort({
				createTime: -1
			})
			.skip(skip)
			.limit(pageSize)

		const res = await aggregate.end()
		return {
			errCode: 0,
			data: res.data
		}
	},

	// 获取评论列表
	async getComments(params) {
		const { postId, page = 1, pageSize = 20 } = params
		
		try {
			const res = await db.collection('article_comments')
				.aggregate()
				.match({
					postId,
					status: 1
				})
				.lookup({
					from: 'uni-id-users',
					localField: 'userId',
					foreignField: '_id',
					as: 'userInfo'
				})
				.unwind('$userInfo')
				.sort({
					createTime: -1
				})
				.skip((page - 1) * pageSize)
				.limit(pageSize)
				.end()
				
			return {
				errCode: 0,
				data: res.data
			}
		} catch (error) {
			console.error('获取评论列表失败：', error)
			return {
				errCode: 500,
				errMsg: '获取评论列表失败'
			}
		}
	}
}